package org.scohen.juploadr.ui;

import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;

public abstract class Task extends Thread {
    private ProgressDialog dialog;
    private Display display;
    protected int min;
    protected int max;

    protected Task() {
        display = ReusableUIFactory.getInstance().getDisplay();
    }

    protected void updateProgress(final int i) {
        Runnable r = new Runnable() {
            public void run() {
                if (!dialog.bar.isDisposed()) {
                    dialog.bar.setSelection(i);
                }
            }
        };
        display.syncExec(r);
        updateMessage(getMessage());
    }

    protected void updateMessage() {
        this.updateMessage(getMessage());
    }

    protected void updateMessage(final String message) {

        Runnable r = new Runnable() {
            public void run() {
                final String croppedMessage = getCroppedMessage(message);
                if (!dialog.msgLabel.isDisposed()) {
                    dialog.msgLabel.setText(croppedMessage);
                    dialog.shell.redraw();
                }
            }
        };
        display.syncExec(r);
    }

    private String getCroppedMessage(String message) {
        GC gc = new GC(dialog.msgLabel);
        Point msgSize = dialog.msgLabel.getSize();
        StringBuffer cropped = new StringBuffer();
        if (gc.textExtent(message).x > msgSize.x) {
            String[] words = message.split(" ");
            for (int i = 0; i < words.length; i++) {
                int oldLength = cropped.length();
                cropped.append(words[i]);

                if (gc.textExtent(cropped.toString()).x > msgSize.x) {
                    // take off the last word, append a \n, and append the word
                    cropped.delete(oldLength, cropped.length());
                    cropped.append("\n");
                    cropped.append(words[i]);
                }
                cropped.append(" ");
            }
            message = cropped.toString();
        }
        gc.dispose();
        return message;
    }

    public abstract void execute();

    public abstract String getMessage();

    public final void run() {
        execute();
        Runnable r = new Runnable() {
            public void run() {
                dialog.close();
            }
        };

        display.asyncExec(r);
    }

    public void setParent(ProgressDialog dialog) {
        this.dialog = dialog;
        dialog.setMax(max);
        dialog.setMin(min);
        dialog.setMessage(getMessage());
    }

    public Image getIcon() {
        return ReusableUIFactory.getInstance().getLogoImage();
    }

    public abstract String getTitle();
}
